--[[
-- @Author: 671643387@qq.com
-- @Date: 2025-05-05 09:50
-- @Description: 能源站信息展示
--]]

local component = require("component")
local text = require("text")
local serialization = require("serialization")
local sides = require("sides")
local oc_util = require("UTIL.oc_util")
local gpu = component.gpu

-- 高位线
local HIGH_POS_LINE = 80
-- 中位线
local MIDDLE_POS_LINE = 50
-- 低位线
local LOW_POS_LINE = 20

return {
    -- 机器方块的地址
    machine_address = nil,
    -- 机器方块
    machine_proxy = nil,
    -- 红石方块地址
    redstone_address = nil,
    -- 红石方块
    redstone_proxy = nil,
    -- 高位线发射面
    high_pos_side = nil,
    -- 中位线发射面
    middle_pos_side = nil,
    -- 低位线发射面
    low_pos_side = nil,
    -- 高位开关状态
    high_running =false,
    -- 中位开关状态
    middle_running = false,
    -- 低位开关状态
    low_running =false,

    -- 初始化
    init = function (self)
        -- 获取所有组件
        local components = oc_util.get_components()

        -- 读取保存的数据
        if not self:loaddata() then
            -- 获取连接的组件数量
            local size = oc_util.get_table_size(components)

            -- 选择机器方块
            repeat
                print("Select machine block:")
                oc_util.print_itable(components, "  ")
                local i = oc_util.read_int()
                if i <= size then
                    self.machine_address = oc_util.get_itable(components, i)
                end
            until self.machine_address ~= nil and #self.machine_address > 0

            -- 选择红石方块
            repeat
                print("Select redstone block:")
                oc_util.print_itable(components, "  ")
                local i = oc_util.read_int()
                if i <= size then
                    self.redstone_address = oc_util.get_itable(components, i)
                end
            until self.redstone_address ~= nil and #self.redstone_address > 0

            -- 获取红石
            self.redstone_proxy = component.proxy(self.redstone_address)

            -- 选面表
            local sides_table = {
                ["front"] = sides.front,
                ["back"] = sides.back,
                ["left"] = sides.left,
                ["right"] = sides.right,
            }
            size = 4

            -- 清空信号
            oc_util.clear_redstone(self.redstone_proxy)

            -- 选择高位线所在面
            repeat
                print("Select high pos line side:")
                oc_util.print_itable(sides_table, "  ")
                local i = oc_util.read_int()
                if i <= size then
                    _, self.high_pos_side = oc_util.get_itable(sides_table, i)
                end

                if self.high_pos_side ~= nil then
                    self.redstone_proxy.setOutput(self.high_pos_side, 15)
                    print("Is it right: (y/n)")
                    local anwser = oc_util.read_str()
                    self.redstone_proxy.setOutput(self.high_pos_side, 0)
                    if anwser == "y" then
                        break
                    end
                end
            until false

            -- 选择中位线所在面
            repeat
                print("Select middle pos line side:")
                oc_util.print_itable(sides_table, "  ")
                local i = oc_util.read_int()
                if i <= size then
                    _, self.middle_pos_side = oc_util.get_itable(sides_table, i)
                end

                if self.middle_pos_side ~= nil then
                    self.redstone_proxy.setOutput(self.middle_pos_side, 15)
                    print("Is it right: (y/n)")
                    if oc_util.read_str() == "y" then
                        self.redstone_proxy.setOutput(self.middle_pos_side, 0)
                        break
                    end
                end
            until false

            -- 选择低位线所在面
            repeat
                print("Select middle pos line side:")
                oc_util.print_itable(sides_table, "  ")
                local i = oc_util.read_int()
                if i <= size then
                    _, self.low_pos_side = oc_util.get_itable(sides_table, i)
                end

                if self.low_pos_side ~= nil then
                    self.redstone_proxy.setOutput(self.low_pos_side, 15)
                    print("Is it right: (y/n)")
                    if oc_util.read_str() == "y" then
                        self.redstone_proxy.setOutput(self.low_pos_side, 0)
                        break
                    end
                end
            until false


            -- 保存数据
            self:savedata()
        end

        -- 获取机器
        self.machine_proxy = component.proxy(self.machine_address)
        -- 获取红石
        self.redstone_proxy = component.proxy(self.redstone_address)

        -- 清空信号
        oc_util.clear_redstone(self.redstone_proxy)
    end,

    -- 保存数据
    savedata = function (self)
        oc_util.save_file("./power_station.dat",
                serialization.serialize({self.machine_address, self.redstone_address,
                self.high_pos_side, self.middle_pos_side, self.low_pos_side}))
    end,

    -- 加载保存的数据
    loaddata = function (self)
        local data = oc_util.read_file("./power_station.dat")
        if data then
            local table = serialization.unserialize(data)
            if table then
                self.machine_address = table[1]
                self.redstone_address = table[2]
                self.high_pos_side = table[3]
                self.middle_pos_side = table[4]
                self.low_pos_side = table[5]
                return self.machine_address and self.redstone_address
            end
        end
        return false
    end,

    -- 运行
    run = function (self)
        -- 横坐标偏移
        local x_offset = 1
        -- 纵坐标偏移
        local y_offset = 1
        -- 获取分辨率
        local width, height = gpu.getResolution()

        -- 清空背景
        gpu.setBackground(0x000000)
        gpu.fill(1, 1, width, height, " ")

        local eu_capacity = self.machine_proxy.getEUCapacity()
        gpu.set(x_offset, y_offset, string.format("最大容量：%s EU",
            text.padLeft(oc_util.formatNumberWithCommas(eu_capacity), 80)))

        -- 显示动态信息
        while true do
            local eu_stored = self.machine_proxy.getEUStored()
            local eu_percent = eu_stored / eu_capacity * 100

            -- 高位发电控制
            if eu_percent < HIGH_POS_LINE and not self.high_running then
                self.high_running = true
                self.redstone_proxy.setOutput(self.high_pos_side, 15)
            elseif eu_percent >= 90 and self.high_running then
                self.high_running = false
                self.redstone_proxy.setOutput(self.high_pos_side, 0)
            end

            -- 中位发电控制
            if eu_percent < MIDDLE_POS_LINE and not self.middle_running then
                self.middle_running = true
                self.redstone_proxy.setOutput(self.middle_pos_side, 15)
            elseif eu_percent >= HIGH_POS_LINE and self.middle_running then
                self.middle_running = false
                self.redstone_proxy.setOutput(self.middle_pos_side, 0)
            end

            -- 低位发电控制
            if eu_percent < LOW_POS_LINE and not self.low_running then
                self.low_running = true
                self.redstone_proxy.setOutput(self.low_pos_side, 15)
            elseif eu_percent >= MIDDLE_POS_LINE and self.low_running then
                self.low_running = false
                self.redstone_proxy.setOutput(self.low_pos_side, 0)
            end

            gpu.set(x_offset, y_offset + 1, string.format("当前储存：%s EU",
                text.padLeft(oc_util.formatNumberWithCommas(eu_stored), 80)))
            gpu.set(x_offset, y_offset + 2, string.format("平均输入：%s EU",
                text.padLeft(oc_util.formatNumberWithCommas(self.machine_proxy.getEUInputAverage()), 80)))
            gpu.set(x_offset, y_offset + 3, string.format("平均输出：%s EU",
                text.padLeft(oc_util.formatNumberWithCommas(self.machine_proxy.getEUOutputAverage()), 80)))
            gpu.set(x_offset, y_offset + 4, string.format("存储占比：%s %%",
                text.padLeft(string.format("%.8f", eu_percent), 80)))

            gpu.set(x_offset, y_offset + 6, string.format("高位发电：%s ==",
                text.padLeft(self.high_running and "上线" or "下线", 80)))
            gpu.set(x_offset, y_offset + 7, string.format("中位发电：%s ==",
                text.padLeft(self.middle_running and "上线" or "下线", 80)))
            gpu.set(x_offset, y_offset + 8, string.format("低位发电：%s ==",
                text.padLeft(self.low_running and "上线" or "下线", 80)))

            local c, b = gpu.getBackground()
            local w = math.ceil(eu_percent / 100 * width)
            gpu.setBackground(0xff0000)
            gpu.fill(1, height - 8 + 1, w, 8, " ")
            gpu.setBackground(0x000000)
            gpu.fill(w + 1, height - 8 + 1, width - w, 8, " ")
            gpu.setBackground(c, b)
        end
    end
}